import express from 'express';
import cors from 'cors';
import fetch from 'node-fetch';
import OpenAI from "openai";
import pptxgen from 'pptxgenjs'; // 新增 PPT 生成库

const app = express();
app.use(cors());
app.use(express.json());


const openai = new OpenAI({
    baseURL: "http://localhost:11434/v1", // Pointing to Ollama's local API
    apiKey: "ollama", // Required by the OpenAI SDK, but Ollama doesn’t validate it
});

// 代理Ollama原生EventStream接口
app.get('/chat/postChat', async (req, res) => {
  try {
    // const { messages } = req.body; // post获取参数
    const { message } = req.query; // get获取参数
    console.log('接收到的消息：', message);
    // 转换为Ollama需要的格式
    const ollamaPayload = {
      model: "deepseek-r1:1.5b",
      prompt: message,
      stream: true
    };

    // 连接Ollama原生流式接口
    const ollamaResponse = await fetch('http://localhost:11434/api/generate', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(ollamaPayload),
      timeout: 600000
    });

    // 设置EventStream响应头
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    // 流式转发Ollama响应
    for await (const chunk of ollamaResponse.body) {
      const data = chunk.toString();
      if (data) {
        const parsed = JSON.parse(data);
        console.log(parsed.response)
        res.write(`data: ${parsed.response}\n\n`); // 提取有效字段
      }
    }
    
    res.write('data: [DONE]\n\n');
    res.end();
  } catch (error) {
    console.error('Ollama连接失败:', error);
    res.status(503).json({ error: '请确认已运行 ollama run deepseek-r1:1.5b' });
  }
});

// 新增路由：生成PPT
app.post('/chat/generate-ppt', async (req, res) => {
  try {
    const { topic } = req.body;
    const sanitizedTopic = topic.replace(/[^a-zA-Z0-9\u4e00-\u9fa5\s]/g, '');
    console.log("生成PPT请求", topic)
    // 1. 生成PPT大纲
    const outlineRes = await openai.chat.completions.create({
      model: "deepseek-r1:1.5b",
      messages: [{
        role: "user",
        content: `生成关于"${sanitizedTopic}"的PPT大纲，输出严格JSON格式：{outline:["标题1","标题2"]}`
      }],
      response_format: { type: "json_object" }
    });
    console.log("ai生成PPT大纲", outlineRes)
    const outline = JSON.parse(outlineRes.choices[0].message.content).outline || [];
    
    // 2. 并行生成所有幻灯片内容
    const slidePromises = outline?.map(title =>
      openai.chat.completions.create({
        model: "deepseek-r1:1.5b",
        messages: [{
          role: "user",
          content: `为幻灯片"${title}"生成3个要点，输出严格JSON格式：{points:["要点1","要点2"]}`
        }],
        response_format: { type: "json_object" }
      })
    );
    console.log("生成待组合内容", slidePromises)
    const slidesContent = await Promise.all(slidePromises);
    const slidesData = slidesContent.map((res, i) => ({
      title: outline[i],
      points: JSON.parse(res.choices[0].message.content).points
    }));
    
    // 3. 生成PPT文件
    const pptx = new pptxgen();
    
    // 应用主题样式
    pptx.defineSlideMaster({
      title: 'DEFAULT',
      background: { color: 'FFFFFF' },
      objects: [{
        rect: { x: 0.0, y: 5.5, w: '100%', h: 0.75, fill: { color: 'F1F1F1' } }
      }]
    });
    
    // 添加幻灯片
    slidesData.forEach((slide, idx) => {
      const pptSlide = pptx.addSlide({ masterName: 'DEFAULT' });
      pptSlide.addText(slide.title, {
        x: 0.5, y: 0.5, w: 9, h: 1,
        fontSize: 24, bold: true, color: '2A2A2A'
      });
      
      slide.points.forEach((point, i) => {
        pptSlide.addText(`• ${point}`, {
          x: 1.0, y: 1.8 + i * 0.8, w: 8, h: 0.7,
          fontSize: 18, bullet: { indent: 0.5 }
        });
      });
      
      // 添加页码
      pptSlide.addText(`${idx + 1}/${slidesData.length}`, {
        x: 9.0, y: 6.8, w: 1, align: 'right',
        fontSize: 12, color: '7F7F7F'
      });
    });
    
    // 4. 生成文件流并返回
    const buffer = await pptx.stream();
    const fileName = `${sanitizedTopic}.pptx`;
    
    res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.presentationml.presentation');
    res.setHeader('Content-Disposition', `attachment; filename=${encodeURIComponent(fileName)}`);
    console.log("PPT生成成功", fileName, buffer)
    res.send(buffer);
    
  } catch (error) {
    console.error(`PPT生成失败: ${error}`);
    res.status(500).json({ error: '生成失败，请检查模型服务' });
  }
});
const PORT = 3001;
app.listen(PORT, () => {
  console.log(`代理服务运行在 http://localhost:${PORT}`);
});